package com.telit.firecommand.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.telit.common.constant.RoleCodeConstants;
import com.telit.common.core.utils.FeignUtils;
import com.telit.common.dto.DistrictDTO;
import com.telit.common.entity.PageData;
import com.telit.common.enums.ResultCode;
import com.telit.common.exception.ForestBaseException;
import com.telit.common.util.GeoUtils;
import com.telit.common.util.LanguageUtils;
import com.telit.common.util.TimeUtils;
import com.telit.common.vo.user.Result;
import com.telit.firecommand.constant.FireConstant;
import com.telit.firecommand.dao.AppTaskFeedbackDao;
import com.telit.firecommand.dao.AppUserLocationDao;
import com.telit.firecommand.dao.GeoXzqhCunDao;
import com.telit.firecommand.dao.SysUserDAO;
import com.telit.firecommand.dto.*;
import com.telit.firecommand.entity.AppTaskFeedback;
import com.telit.firecommand.entity.AppUserLocation;
import com.telit.firecommand.entity.SysUser;
import com.telit.firecommand.feign.PatrolFeignClient;
import com.telit.firecommand.service.DistrictService;
import com.telit.firecommand.service.SysUserService;
import com.telit.firecommand.vo.*;
import com.telit.upms.feign.RemoteUpmsService;
import com.telit.upms.vo.MicroSysUserAllInfoVo;
import com.telit.upms.vo.MicroSysUserVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * @Auther amy
 * @Describe
 */
@Service
@Slf4j
public class ForesterService {

    @Autowired
    private DistrictService districtService;

    @Autowired
    private AppUserLocationDao appUserLocationDao;

    @Autowired
    private GeoXzqhCunDao geoXzqhCunDao;

    @Autowired
    private PatrolFeignClient patrolFeignClient;

    @Autowired
    private RemoteUpmsService remoteUpmsService;

    @Autowired
    private AppTaskFeedbackDao appTaskFeedbackDao;

    @Autowired
    private SysUserDAO sysUserDAO;

    @Autowired
    private SysUserService sysUserService;

    /**
     * 护林下拉列表
     *
     * @return
     */
    public List<ForesterDTO> foresterSelect(Integer status, String name, Long orgId, String longitude,
                                            String latitude, String areaCode, String radius) {
        List<ForesterDTO> list = listByCondition(areaCode, status, name, orgId);
//        PageData pageData = qryList(status, name, areaCode, 1, 5000);
//        Object datas = pageData.getDatas();
        // 查询护林员位置离火点位置的距离
        if (!CollectionUtil.isEmpty(list)) {
            if (!StringUtils.isEmpty(longitude) && !StringUtils.isEmpty(latitude)) {
                List<ForesterDTO> foresterDTOList;
                if (!CollectionUtils.isEmpty(list)) {
                    list.forEach(foresterInfoDTO -> {
                        if (!StringUtils.isEmpty(foresterInfoDTO.getLongitude()) && !StringUtils.isEmpty(
                                foresterInfoDTO.getLatitude())) {
                            foresterInfoDTO.setFireDistance(
                                    fireDistance(foresterInfoDTO.getLongitude(), foresterInfoDTO.getLatitude(),
                                            longitude,
                                            latitude));
                        }
                    });
                }

//                取距离火场最近的10个护林员
                foresterDTOList = list.stream()
//                        .filter(f -> f.getFireDistance() != null)
//                        .sorted(Comparator.comparing(ForesterDTO::getFireDistance))
                        .sorted((o1, o2) -> {
                            if (o1.getLoginStatus() > o2.getLoginStatus()) {
                                return -1;
                            } else if (o1.getLoginStatus().equals(o2.getLoginStatus())) {
                                if (o1.getFireDistance() != null && o2.getFireDistance() != null) {
                                    return o1.getFireDistance().compareTo(o2.getFireDistance());
                                }
                                return o1.getId().compareTo(o2.getId());
                            } else {
                                if (o1.getFireDistance() != null && o2.getFireDistance() != null) {
                                    return o1.getFireDistance().compareTo(o2.getFireDistance());
                                }
                                return 1;
                            }
                        })
//                        .limit(10)
                        .collect(Collectors.toList());

                //如果radius不为null的话 计算周边范围内的护林员
                if (radius != null) {
                    foresterDTOList = foresterDTOList.stream()
                            .filter(f -> f.getFireDistance() != null)
                            .filter(
                                    foresterDTO -> GeoUtils.sub(foresterDTO.getFireDistance(), radius) < 0).collect(
                                    Collectors.toList());
                }
                return foresterDTOList;
            }
        }
        return list;
    }

    /**
     * 护林员信息
     *
     * @return
     */
    public List<ForesterDTO> listByCondition(String districtCode, Integer status, String name, Long orgId) {
        PageData<List<ForesterVO>> pageData = sysUserService.qryList(status, name, districtCode, true,
                RoleCodeConstants.ROLE_CODE_FORESTER, null, 1, Integer.MAX_VALUE);
        List<ForesterVO> foresterVOList = pageData.getDatas();
        if (foresterVOList != null) {
            //  List<SysUserShortVo> list = JSON.parseArray(JSON.toJSON(result.getData()).toString(), SysUserShortVo.class);
            // 将统一平台的用户数据转成业务平台的数据
            return sysUserShortVoToForesterDTO(foresterVOList);
        }

        return null;
    }


    /**
     * 获取距离火场距离
     */
    public String fireDistance(String longitude, String latitude, String fireLongitude, String fireLatitude) {
        String fireDistanceStr = StringUtil.EMPTY;
        // 查询护林员位置离火点位置的距离
        if (!StringUtils.isEmpty(fireLongitude) && !StringUtils.isEmpty(fireLatitude)) {
            if (!StringUtils.isEmpty(longitude) && !StringUtils.isEmpty(latitude)) {
                Double fireDistance = GeoUtils.GetDistanceTwo(new Double(fireLongitude), new Double(fireLatitude),
                        new Double(longitude), new Double(latitude));
                fireDistanceStr =
                        new BigDecimal(fireDistance).multiply(new BigDecimal(1000)).divide(new BigDecimal(1000), 3,
                                BigDecimal.ROUND_HALF_UP) + "";
            }
        }
        return fireDistanceStr;
    }

    /**
     * 根据用户id查询经纬度
     *
     * @return
     */
    public AppUserLocation getLocation(Long userId) {
        QueryWrapper<AppUserLocation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        return appUserLocationDao.selectOne(queryWrapper);
    }

    /**
     * 将统一平台的用户数据转成业务平台的数据,设置经纬度
     *
     * @return
     */
    private List<ForesterDTO> sysUserShortVoToForesterDTO(List<ForesterVO> list) {
        if (!CollectionUtils.isEmpty(list)) {
            List<ForesterDTO> foresterInfoDTOList = new ArrayList<>();
            list.forEach(sysUserShortVo -> {
                ForesterDTO foresterInfoDTO = new ForesterDTO();
                BeanUtils.copyProperties(sysUserShortVo, foresterInfoDTO);
                // 为了前端字段变动不大，后台做转换
                foresterInfoDTO.setRealname(sysUserShortVo.getRealName());
                foresterInfoDTO.setLoginStatus(sysUserShortVo.getUserOnlineStatus());
                if (sysUserShortVo.getBirthday() != null) {
                    foresterInfoDTO.setAge(TimeUtils.getAge(new Date(sysUserShortVo.getBirthday())));// 设置年龄
                }
                foresterInfoDTO.setMobile(sysUserShortVo.getMobile());
                foresterInfoDTO.setDistrictCode(sysUserShortVo.getAreaCode());
                foresterInfoDTO.setDistrictName(sysUserShortVo.getAreaCn());
                foresterInfoDTO.setGender(sysUserShortVo.getGender());
                foresterInfoDTO.setGenderName(sysUserShortVo.getGenderCn());
                foresterInfoDTO.setDetailAddress(sysUserShortVo.getAddress());
                foresterInfoDTOList.add(foresterInfoDTO);

            });
            //按在离线状态排序
            List<ForesterDTO> foresterDTOList = foresterInfoDTOList.stream().sorted(
                    Comparator.comparing(ForesterDTO::getLoginStatus).reversed()).collect(Collectors.toList());
            return foresterDTOList;
        }
        return null;
    }

//    /**
//     * 查询每级行政区划下的护林员数量
//     *
//     * @param code
//     *
//     * @return
//     */
//    public List<DistrictInfoVo> districtForestCount(String code) {
//        Result result = upmsFeignClient.queryDistrictList(code);
//        List<DistrictInfoVo> list = new ArrayList<>();
//        if (result != null && result.getData() != null) {
//            list = JSON.parseArray(JSON.toJSON(result.getData()).toString(), DistrictInfoVo.class);
//            SysUserRolePageDto sysUserRolePageDto = new SysUserRolePageDto();
//            sysUserRolePageDto.setRoleCode(RoleCodeConstants.ROLE_CODE_FORESTER);
//            list.forEach(e -> {
//                //获取每级行政区划下的护林员数量
//                int count = countByCondition(e.getCode(), null, null);
//                e.setUserCount(count);
//            });
//        }
//        return list;
//    }

    /**
     * 获取护林员数量
     *
     * @param districtCode 行政区域code
     * @param status       在线状态
     * @param name         护林员名称
     *
     * @return 数量
     */
    public int countByCondition(String districtCode, Integer status, String name) {
        long total = sysUserDAO.count(status, name, districtCode, true, RoleCodeConstants.ROLE_CODE_FORESTER_ID, null,
                null);
        return (int) total;
    }

    public List<ForesterVO> listByCondition(String districtCode, Integer status, String name, boolean areaRecursion) {
        PageData<List<ForesterVO>> pageData = sysUserService.qryList(status, name, districtCode, areaRecursion,
                RoleCodeConstants.ROLE_CODE_FORESTER, null, 1, Integer.MAX_VALUE);
        return pageData.getDatas();
    }

    /**
     * 查询树形行政区划
     *
     * @param status       状态
     * @param name         名称
     * @param districtCode 行政区划编码
     *
     * @return DistrictCountDTO
     */
    public DistrictCountDTO listByDistrict(Integer status, String name, String districtCode) {
        if (districtCode.length() >= FireConstant.DISTRICT_VILLAGE_CODE_LENGTH) {//村
            return null;
        }

        //当前行政区划信息
        DistrictDTO current = districtService.qryDistrictInfo(districtCode);
        //当前行政区划下护林员数量（包含子行政区划）
        int currentCount = countByCondition(districtCode, status, name);
        //当前行政区划下护林员列表（不包含子行政区划）
        List<ForesterVO> currentForestList = new ArrayList<>();
        if (currentCount > 0) {
            currentForestList = listByCondition(districtCode, status, name, false);
        }
        //构建返回DTO
        DistrictCountDTO districtCountDTO = DistrictCountDTO.builder()
                .id(current.getId())
                .name(current.getName())
                .code(current.getCode())
                .parentCode(current.getParentCode())
                .rank(current.getRank())
                .count(currentCount)
                .foresterList(currentForestList)
                .build();
        List<DistrictCountDTO> countChildren = new ArrayList<>();
        //子类行政区划集合
        List<DistrictDTO> children = districtService.qryListByParentCode(districtCode, null);
        children.forEach(districtDTO -> {
            int childCount = countByCondition(districtDTO.getCode(), status, name);
            List<ForesterVO> childForestList = new ArrayList<>();
            if (childCount > 0) {
                childForestList = listByCondition(districtDTO.getCode(), status, name, false);
            }
            DistrictCountDTO countDTO = DistrictCountDTO.builder()
                    .id(districtDTO.getId())
                    .name(districtDTO.getName())
                    .code(districtDTO.getCode())
                    .parentCode(districtDTO.getParentCode())
                    .rank(districtDTO.getRank())
                    .count(childCount)
                    .foresterList(childForestList)
                    .build();
            countChildren.add(countDTO);
        });
        districtCountDTO.setChildren(countChildren);
        return districtCountDTO;
    }


    /**
     * 查询护林员列表
     *
     * @param onlineStatus 在线状态 0-离线 1-在线
     * @param name         护林员名称
     * @param regionCode   个人所属行政区划编码
     * @param current      当前页数
     * @param size         每页条数
     *
     * @return 分页列表
     */
    public PageData<List<ForesterVO>> qryList(Integer onlineStatus, String name, String regionCode, Integer current,
                                              Integer size) {
        return sysUserService.qryList(onlineStatus, name, regionCode, true, RoleCodeConstants.ROLE_CODE_FORESTER, null,
                current, size);
    }

    public ForesterVO foresterInfoById(Long id) {
        com.telit.common.core.utils.Result<Map<Long, MicroSysUserAllInfoVo>> selectUserContainDeptAndRoleWithBatchIdsResult = remoteUpmsService.selectUserContainDeptAndRoleWithBatchIds(
                Arrays.asList(id), true);
        Map<Long, MicroSysUserAllInfoVo> longMicroSysUserAllInfoVoMap = FeignUtils.unwrap(
                selectUserContainDeptAndRoleWithBatchIdsResult);
        MicroSysUserAllInfoVo microSysUserAllInfoVo = longMicroSysUserAllInfoVoMap.get(id);
        if (microSysUserAllInfoVo == null) {
            throw new ForestBaseException(LanguageUtils.codeMessage(ResultCode.OPERATE_ERROR.getCode(), id));
        }

        SysUser sysUser = sysUserDAO.selectByUserId(id);
        if (sysUser == null) {
            throw new ForestBaseException(LanguageUtils.codeMessage(ResultCode.OPERATE_ERROR.getCode(), id));
        }

        ForesterVO foresterVO = new ForesterVO();
        BeanUtils.copyProperties(microSysUserAllInfoVo, foresterVO);
        foresterVO.setLongitude(sysUser.getLongitude());
        foresterVO.setLatitude(sysUser.getLatitude());
        foresterVO.setUserOnlineStatus(sysUser.getUserOnlineStatus());
        foresterVO.setDistrictCode(sysUser.getDistrictCode());

        return foresterVO;
    }


    public List<ForesterVO> batchFindForesterInfo(List<Long> ids) {
        if (ids != null && ids.size() > 0) {
            List<SysUser> sysUsers = sysUserDAO.selectByIds(ids);
            ids = sysUsers.stream().map(SysUser::getId).collect(Collectors.toList());

            com.telit.common.core.utils.Result<Map<Long, MicroSysUserAllInfoVo>> selectUserContainDeptAndRoleWithBatchIdsResult = remoteUpmsService.selectUserContainDeptAndRoleWithBatchIds(
                    ids, true);
            Map<Long, MicroSysUserAllInfoVo> longMicroSysUserAllInfoVoMap = FeignUtils.unwrap(
                    selectUserContainDeptAndRoleWithBatchIdsResult);

            //处理经纬度
            Map<Long, SysUser> longUserMap = sysUsers.stream().collect(
                    Collectors.toMap(SysUser::getId, Function.identity(), (key1, key2) -> key2));
            //用户集合
            List<MicroSysUserAllInfoVo> microSysUserAllInfoVos = ids.stream().map(
                    longMicroSysUserAllInfoVoMap::get).collect(Collectors.toList());
            List<ForesterVO> foresterVOList = new ArrayList<>();
            microSysUserAllInfoVos.stream().forEach(microSysUserAllInfoVo -> {
                ForesterVO foresterVO = new ForesterVO();
                BeanUtils.copyProperties(microSysUserAllInfoVo, foresterVO);
                //用户经纬度
                SysUser sysUser = longUserMap.get(foresterVO.getId());
                foresterVO.setLongitude(sysUser.getLongitude());
                foresterVO.setLatitude(sysUser.getLatitude());
                foresterVO.setUserOnlineStatus(sysUser.getUserOnlineStatus());
                foresterVOList.add(foresterVO);
            });

            return foresterVOList;
        }
        return null;
    }


    //护林员模块下发任务
    public void releaseTask(TaskReleaseDTO taskReleaseDTO) {
        ReleaseTaskDto releaseTaskDto = new ReleaseTaskDto();
        Result result = null;
        BeanUtils.copyProperties(taskReleaseDTO, releaseTaskDto);
        try {
            result = patrolFeignClient.feignReleaseTask(releaseTaskDto);
            if (result.getCode().equals(ResultCode.SUCCESS.getCode()) && result.getData() != null) {
                return;
            }
        } catch (Exception e) {
            throw new ForestBaseException(ResultCode.SERVER_FEIGN_ERROR.getCode(),
                    ResultCode.SERVER_FEIGN_ERROR.getMsg());
        }
    }

    //护林员模块---查询巡护记录列表
    public PageData patrolList(String startTime, String endTime, String regionCode, Integer current, Integer size,
                               Long protectorId, String personType) {
        PatPersonPatrolInfoPageDto patPersonPatrolInfoPageDto = PatPersonPatrolInfoPageDto.builder()
                .current(current)
                .size(size)
                .startTime(startTime)
                .endTime(endTime)
                .district(regionCode)
                .protectorId(protectorId)
                .personType(personType)
                .build();

        Result personPatrolInfoList = patrolFeignClient.findPersonPatrolInfoList(patPersonPatrolInfoPageDto);
        if (!personPatrolInfoList.isSuccess()) {
            throw new ForestBaseException(personPatrolInfoList.getCode(), null, personPatrolInfoList.getErrorMsg());
        }
        Map data = JSON.parseObject(JSON.toJSONString(personPatrolInfoList.getData()), Map.class);
        List<PatPersonPatrolInfoVo> records = JSON.parseArray(MapUtil.getStr(data, "records"),
                PatPersonPatrolInfoVo.class);
        return PageData.builder()
                .count(MapUtil.getInt(data, "total"))
                .size(patPersonPatrolInfoPageDto.getSize())
                .current(patPersonPatrolInfoPageDto.getCurrent())
                .datas(records)
                .pages(MapUtil.getInt(data, "pages"))
                .build();

    }

    //护林员模块---巡护记录详情
    public TaskInfoVo getPatrolInfoDetail(Long id) {
        Result result = patrolFeignClient.feignReleaseTask(id);
        if (result.getCode().equals(ResultCode.SUCCESS.getCode()) && result.getData() != null) {
            return JSON.parseObject(JSON.toJSONString(result.getData()), TaskInfoVo.class);
        }
        return null;
    }

    //护林员模块---查询巡护任务列表
    public PageData getTaskListByPerson(String releaseStartTime, String releaseEndTime, String taskStartTime,
                                        String taskEndTime, Integer state, Integer taskTypeGrade, String regionCode,
                                        Integer current, Integer size,
                                        Long protectorId) {
        TsTaskInfoPageDto tsTaskInfoPageDto = TsTaskInfoPageDto.builder()
                .current(current)
                .size(size)
                .releaseStartTime(releaseStartTime)
                .releaseEndTime(releaseEndTime)
                .taskStartTime(taskStartTime)
                .taskEndTime(taskEndTime)
                .state(state)
                .taskTypeGrade(taskTypeGrade)
                .district(regionCode)
                .personId(protectorId)
                .build();

        Result personPatrolInfoList = patrolFeignClient.getTaskListByPerson(tsTaskInfoPageDto);
        if (!personPatrolInfoList.isSuccess()) {
            throw new ForestBaseException(personPatrolInfoList.getCode(), null, personPatrolInfoList.getErrorMsg());
        }
        Map data = JSON.parseObject(JSON.toJSONString(personPatrolInfoList.getData()), Map.class);
        List<TaskInfoListVo> records = JSON.parseArray(MapUtil.getStr(data, "records"), TaskInfoListVo.class);
        return PageData.builder()
                .count(MapUtil.getInt(data, "total"))
                .size(tsTaskInfoPageDto.getSize())
                .current(tsTaskInfoPageDto.getCurrent())
                .datas(records)
                .pages(MapUtil.getInt(data, "pages"))
                .build();

    }

    public TaskInfoVo getTaskDetail(Long taskId, Long userId) {
        Result result = patrolFeignClient.findTaskInfoDetail(taskId, userId);
        if (result.getCode().equals(ResultCode.SUCCESS.getCode()) && result.getData() != null) {
            return JSON.parseObject(JSON.toJSONString(result.getData()), TaskInfoVo.class);
        }
        return null;
    }

    public PageData findForesterByFireId(String fireId) {
        //任务信息按照下达人员进行展示；人员排序规则：按照第一次反馈时间顺序排序
        List<AppTaskFeedback> appTaskFeedbacksInfo = appTaskFeedbackDao.queryFireFeedback(
                Long.parseLong(fireId))
                .stream()
                .sorted(Comparator.comparing(AppTaskFeedback::getFeedbackTime, Comparator.nullsFirst(Date::compareTo)))
                //根据任务下发人去重
                .collect(Collectors.collectingAndThen(Collectors.toCollection(
                        () -> new TreeSet<>(Comparator.comparing(AppTaskFeedback::getIssueTaskId))), ArrayList::new));
        List<Long> personIds = appTaskFeedbacksInfo.stream().map(AppTaskFeedback::getIssueTaskId).distinct().collect(
                Collectors.toList());
        //获取接收人数据集合
        com.telit.common.core.utils.Result<Map<Long, MicroSysUserVo>> selectByBatchIdsResult = remoteUpmsService.selectByBatchIds(
                personIds, true);
        Map<Long, MicroSysUserVo> microSysUserVoMap = FeignUtils.unwrap(selectByBatchIdsResult);

        List<Map<String, String>> forestList = new ArrayList<>();
        personIds.forEach(e -> {
            if (microSysUserVoMap.get(e) != null) {
                Map<String, String> forestMap = new HashMap<>();
                forestMap.put("fireId", fireId);
                forestMap.put("personId", Convert.toStr(e));
                forestMap.put("personName", microSysUserVoMap.get(e).getRealName());
                forestList.add(forestMap);
            }
        });

        return PageData.builder()
                .count(forestList.size())
                .size(Integer.MAX_VALUE)
                .current(1)
                .datas(forestList)
                .pages(1)
                .build();

    }

    public PageData findTaskByForesterIdAndFireId(String fireId, String personId) {
        Result result = patrolFeignClient.findTaskListForFireId(fireId, 1, 1000000, personId);
        if (!result.isSuccess()) {
            return null;
        }
        Map data = JSON.parseObject(JSON.toJSONString(result.getData()), Map.class);
        List<FireHlyTaskListVo> records = JSON.parseArray(MapUtil.getStr(data, "records"), FireHlyTaskListVo.class);
        return PageData.builder()
                .count(MapUtil.getInt(data, "total"))
                .size(Integer.MAX_VALUE)
                .current(1)
                .datas(records)
                .pages(MapUtil.getInt(data, "pages"))
                .build();

    }


    public List<FeignTaskNumVo> countForTask(String district, Long userId) {
        FeignTaskNumDto feignTaskNumDto = FeignTaskNumDto.builder()
                .district(district)
                .userId(userId)
                .build();
        Result<List<FeignTaskNumVo>> listResult = patrolFeignClient.countForTask(feignTaskNumDto);
        if (listResult.getCode().equals(ResultCode.SUCCESS.getCode()) && listResult.getData() != null) {
            List<FeignTaskNumVo> collect = listResult.getData().stream().filter(
                    feignTaskNumVo -> feignTaskNumVo.getTaskTypeGrade() != 7).collect(Collectors.toList());
            return JSON.parseArray(JSON.toJSONString(collect), FeignTaskNumVo.class);
        }
        return null;
    }

    /**
     * 查询几公里范围内的护林员列表
     *
     * @param longitude  经度
     * @param latitude   纬度
     * @param regionCode 行政区划编码
     * @param distance   距离（公里）
     *
     * @return List<ForesterVO>
     */
    public List<ForesterVO> qryListByDistance(String longitude, String latitude, String regionCode, String distance) {
        List<SysUser> sysUsers = sysUserDAO.selectByDistance(longitude, latitude, regionCode, distance);
        if (CollectionUtil.isEmpty(sysUsers)) {
            return new ArrayList<>();
        }

        List<Long> ids = sysUsers.stream().map(SysUser::getId).collect(Collectors.toList());
        com.telit.common.core.utils.Result<Map<Long, MicroSysUserAllInfoVo>> selectUserContainDeptAndRoleWithBatchIdsResult = remoteUpmsService.selectUserContainDeptAndRoleWithBatchIds(
                ids, true);
        Map<Long, MicroSysUserAllInfoVo> longMicroSysUserAllInfoVoMap = FeignUtils.unwrap(
                selectUserContainDeptAndRoleWithBatchIdsResult);

        //处理经纬度
        Map<Long, SysUser> longUserMap = sysUsers.stream().collect(
                Collectors.toMap(SysUser::getId, Function.identity(), (key1, key2) -> key2));
        //用户集合
        List<MicroSysUserAllInfoVo> microSysUserAllInfoVos = ids.stream().map(
                longMicroSysUserAllInfoVoMap::get).collect(Collectors.toList());
        List<ForesterVO> foresterVOList = new ArrayList<>();
        microSysUserAllInfoVos.stream().forEach(microSysUserAllInfoVo -> {
            ForesterVO foresterVO = new ForesterVO();
            BeanUtils.copyProperties(microSysUserAllInfoVo, foresterVO);
            //用户经纬度
            SysUser sysUser = longUserMap.get(foresterVO.getId());
            foresterVO.setLongitude(sysUser.getLongitude());
            foresterVO.setLatitude(sysUser.getLatitude());
            foresterVO.setUserOnlineStatus(sysUser.getUserOnlineStatus());
            foresterVOList.add(foresterVO);
        });
        return foresterVOList;
    }

    /**
     * 查询临时账号，为了满足演示
     */
    public List<ForesterDTO> qryTempForester(String longitude, String latitude) {
        String realName = "yichang";
        SysUser sysUser = sysUserDAO.selectByRealName(realName);
        if (sysUser == null) {
            return null;
        }
        PageData<List<ForesterVO>> pageData = sysUserService.qryList(null, null, null, false, null,
                sysUser.getId().toString(), 1, 1);
        List<ForesterVO> datas = pageData.getDatas();
        List<ForesterDTO> foresterDTOS = sysUserShortVoToForesterDTO(datas);
        if (StrUtil.isNotEmpty(longitude) && StrUtil.isNotEmpty(latitude)) {
            foresterDTOS.forEach(foresterInfoDTO -> {
                if (!StringUtils.isEmpty(foresterInfoDTO.getLongitude()) && !StringUtils.isEmpty(
                        foresterInfoDTO.getLatitude())) {
                    foresterInfoDTO.setFireDistance(
                            fireDistance(foresterInfoDTO.getLongitude(), foresterInfoDTO.getLatitude(), longitude,
                                    latitude));
                }
            });
        }
        return foresterDTOS;
    }

}
